﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO; // TextReader, TextWriter

namespace simWaifu
{
    class ChatLogger
    {
        //
        // Data
        //

        // flags for log behaviour:
        // if bShowErrors is true, calls of WriteError() will be logged.
        // if bShowEverything is true, calls of WriteMsg() will be logged, too.
        public static bool bLogChat = true;
        public static bool bInitialized = false;

        // chat log form
        static FormChatLog frmChat = null;

        //
        // Public Methods
        //

        //public static void WriteError(string s)
        //{
        //    if (bLogErrors)
        //        Write(s);
        //}

        //public static void WriteErrorLine(string s)
        //{
        //    WriteError(s);
        //    WriteError(Environment.NewLine);
        //}

        public static void WriteChat(string s)
        {
            if (bLogChat)
                Write(s);
        }

        public static void WriteChatLine(string s)
        {
            WriteChat(s);
            WriteChat(Environment.NewLine);
        }

        public static void Initialize()
        {
            //TextWriter writer = null;

            string chatFileName = GetChatFileName();
            try
            {
                //writer = new StreamWriter(debugFileName, false);
                WriteLine("");
                WriteLine("##################################################");
                WriteLine("simWaifu " + Properties.Settings.Default.AppVersion + " ChatLog");
                //WriteLine("ChatFileName: " + chatFileName);
                WriteLine("Date+Time this session started: " + DateTime.Now.ToString());
                WriteLine("");
            }
            // gotta catch ´em all
            // why can´t I hold all these exceptions?
            // todo: not all of these are necessary anymore (moved writeLine code elsewhere)
            // todo: and some of them can´t even happen to begin with (argument NULL etc)
            // todo: gonna weed them out later
            catch (System.UnauthorizedAccessException)
            {
                Write("ChatMessageHandler.Initialize(): ");
                WriteLine("System.UnauthorizedAccessException");
            }
            catch (System.ArgumentNullException)
            {
                Write("ChatMessageHandler.Initialize(): ");
                WriteLine("System.ArgumentNullException");
            }
            catch (System.ArgumentException)
            {
                Write("ChatMessageHandler.Initialize(): ");
                WriteLine("System.ArgumentException");
            }
            catch (System.IO.FileNotFoundException)
            {
                Write("ChatMessageHandler.Initialize(): ");
                WriteLine("System.IO.FileNotFoundException: " + chatFileName);
            }
            catch (System.IO.DirectoryNotFoundException)
            {
                Write("ChatMessageHandler.Initialize(): ");
                WriteLine("System.IO.DirectoryNotFoundException: " + chatFileName);
            }
            catch (System.IO.PathTooLongException)
            {
                Write("ChatMessageHandler.Initialize(): ");
                WriteLine("System.IO.PathTooLongException" + chatFileName);
            }
            catch (System.Security.SecurityException)
            {
                Write("ChatMessageHandler.Initialize(): ");
                WriteLine("System.Security.SecurityException");
            }
            catch (System.IO.IOException)
            {
                Write("ChatMessageHandler.Initialize(): ");
                WriteLine("System.IO.IOException");
            }
            catch (System.ObjectDisposedException)
            {
                Write("ChatMessageHandler.Initialize(): ");
                WriteLine("System.ObjectDisposedException");
            }
            finally
            {
                // make sure stream is closed
                //if (tr != null)
                //{
                //    tr.Close();
                //}
            }
            bInitialized = true;
        }

        public static void ShutDown()
        {
            /*if (reader != null)
            {
                reader.Close();
                reader = null;
            }*/
            /*
            if (writer != null)
            {
                writer.Close();
                writer = null;
            }*/
            //frmChat = null;
            bInitialized = false;
        }

        public static void ConnectToChatForm(FormChatLog f)
        {
            frmChat = f;
        }

        public static void DisconnectFromChatForm()
        {
            frmChat = null;
        }

        //
        // Private Methods
        //

        public static string GetChatFileName()
        {
            string appDataPath = Application.LocalUserAppDataPath;
            string chatFileName = Path.Combine(appDataPath, "simWaifuChatLog.txt");
            return chatFileName;
        }

        private static void Write(string s)
        {
            //// if connected to chat form, pass string
            if ((frmChat != null) && (!frmChat.IsDisposed))
            {
                frmChat.Write(s);
            }

            TextWriter writer = null;

            string chatFileName = GetChatFileName();
            try
            {
                writer = new StreamWriter(chatFileName, true);
                //writer.WriteLine("simWaifu Debug Output");
                //WriteLine(Properties.Settings.Default.AppVersion);
                //WriteLine("DebugFileName: " + debugFileName);
            }
            // gotta catch ´em all
            // why can´t I hold all these exceptions?
            // todo: not all of these are necessary anymore (moved writeLine code elsewhere)
            // todo: and some of them can´t even happen to begin with (argument NULL etc)
            // todo: gonna weed them out later
            catch (System.UnauthorizedAccessException)
            {
                writer.Write("ChatMessageHandler.Write(): ");
                writer.WriteLine("System.UnauthorizedAccessException");
            }
            catch (System.ArgumentNullException)
            {
                writer.Write("ChatMessageHandler.Write(): ");
                writer.WriteLine("System.ArgumentNullException");
            }
            catch (System.ArgumentException)
            {
                writer.Write("ChatMessageHandler.Write(): ");
                writer.WriteLine("System.ArgumentException");
            }
            catch (System.IO.FileNotFoundException)
            {
                writer.Write("ChatMessageHandler.Write(): ");
                writer.WriteLine("System.IO.FileNotFoundException: " + chatFileName);
            }
            catch (System.IO.DirectoryNotFoundException)
            {
                writer.Write("ChatMessageHandler.Write(): ");
                writer.WriteLine("System.IO.DirectoryNotFoundException: " + chatFileName);
            }
            catch (System.IO.PathTooLongException)
            {
                writer.Write("ChatMessageHandler.Write(): ");
                writer.WriteLine("System.IO.PathTooLongException" + chatFileName);
            }
            catch (System.Security.SecurityException)
            {
                writer.Write("ChatMessageHandler.Write(): ");
                writer.WriteLine("System.Security.SecurityException");
            }
            catch (System.IO.IOException)
            {
                writer.Write("ChatMessageHandler.Write(): ");
                writer.WriteLine("System.IO.IOException");
            }
            catch (System.ObjectDisposedException)
            {
                writer.Write("ChatMessageHandler.Write(): ");
                writer.WriteLine("System.ObjectDisposedException");
            }
            finally
            {
                // make sure stream is closed
                //if (tr != null)
                //{
                //    tr.Close();
                //}
            }

            // if file is open, write string
            if (writer != null)
            {
                try
                {
                    //
                    // Mh, flush() doesn´t ensure that data is written.
                    // Data will be only written completely after writer is closed.
                    // Maybe not a good idea to keep it open all the time;
                    // when the app crashes it´s not ensured that all debug info 
                    // was written to the stream.
                    //
                    // ToDo: close writer after a line was written, reopen for next line
                    //
                    writer.Write(s);
                }
                catch (System.IO.IOException)
                {
                    writer.Write("ChatMessageHandler.Write(): ");
                    writer.WriteLine("System.IO.IOException");
                }
                catch (System.ObjectDisposedException)
                {
                    writer.Write("ChatMessageHandler.Write(): ");
                    writer.WriteLine("System.ObjectDisposedException");
                }
                finally
                {
                    writer.Close();
                    // close writer?
                }
            }
            else
            {
                // writer is null!
            }
        }

        private static void WriteLine(string s)
        {
            Write(s);
            Write(Environment.NewLine);
        }
    }
}
